package com.platform.qujia.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;

/**
 * <Title> QRcodeUtils </Title>
 * <description>二维码生成: 使用Google.ZXing工具包生成二维码图片</description>
 * @author JK
 * @date 2019年11月4日
 */
public class QRcodeUtils {

    //防止中文乱码
    private static final String CHARSET = "utf-8";
    //格式
    private static final String FORMAT_NAME = "JPG";
    //设置二维码尺寸
    private static final int QRCODE_SIZE = 150;
    //设置logo宽度
    private static final int WIDTH = 40;
    //设置logo高度
    private static final int HEIGHT =40;

    /****
     *  生成含有二维码的图片
     * @param file      底层图片
     * @param x         距离左上角的X偏移量
     * @param y         距离左上角的Y偏移量
     * @param alpha     透明度, 选择值从0.0~1.0: 完全透明~完全不透明
     * @param content   二维码内容
     * @param logoImgPath  logo图片地址:不用logo可以为null
     * @param savePath      生成含有二维码的保存路径
     * @param needCompress  logo图片数否需要压缩
     * @param  id 活动id
     * @param inviteesId 邀请人id
     * @return
     * @throws IOException
     * @throws WriterException
     */
    public static String imgContainQRcode(File file, int x, int y, float alpha, String content, String logoImgPath, String savePath, boolean needCompress,Integer id,String inviteesId) throws IOException, WriterException {
        //读取底层图片
        BufferedImage bufferedImage = ImageIO.read(file);
        //获取二维码图片
        BufferedImage qrCodeImg = QRcodeUtils.createImage(content, logoImgPath, needCompress);
        //在底图上开始绘图
        Graphics2D graphics2D = bufferedImage.createGraphics();
        //获取二维码高宽度
        int height = qrCodeImg.getHeight();
        int width = qrCodeImg.getWidth();
        //实现俩张图片混合
        graphics2D.drawImage(qrCodeImg, x, y, height, width, null);
        graphics2D.dispose();

        //判断保存路径文件夹是否存在
        File f = new File(savePath);
        if(!f.exists() && !f.isDirectory()){
            f.mkdir();
        }
        //使用时间戳命名新和成的图片
        //file.getName();
        //String strFile = System.currentTimeMillis() + ".jpg";
        String strFile = id+inviteesId + ".jpg";

        ImageIO.write(bufferedImage, FORMAT_NAME, new File(savePath + "/" + strFile));
        return strFile;
    }
    /*****
     * 生成内嵌logo二维码到指定保存路径
     *  若生成无logo二维码则设置imgLogoPath为null即可
     * @param content   内容
     * @param imgLogoPath   logo图片获取地址
     * @param savePath  生成有logo二维码图片存放地址
     * @param needCompress  是否压缩logo图片
     * @throws IOException
     * @throws WriterException
     */
    public static void encode(String content, String imgLogoPath, String savePath, boolean needCompress) throws IOException, WriterException {

        QRcodeUtils.createImage(content, imgLogoPath, needCompress);
        File file = new File(savePath);
        //判断保存路径文件夹是否存在
        if(!file.exists() && !file.isDirectory()){
            file.mkdir();
        }
        //使用时间戳命名
        String strFile = System.currentTimeMillis() + ".jpg";
        ImageIO.write(QRcodeUtils.createImage(content, imgLogoPath, needCompress), FORMAT_NAME, new File(savePath + "/" + strFile));
    }


    /***
     * 生成含有logo二维码图片
     * @param content :内容
     * @param imgPath   :logo地址
     * @param needCompress :是否压缩
     * @return
     * @throws WriterException
     * @throws IOException
     */
    public static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws WriterException, IOException {
        Hashtable<EncodeHintType, Object> hint = new Hashtable<EncodeHintType, Object>();
        hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //设置编码
        hint.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hint.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix =
                new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hint);
        //创建图片
        BufferedImage image =
                new BufferedImage(bitMatrix.getWidth(), bitMatrix.getHeight(), BufferedImage.TYPE_INT_RGB);
        for(int i=0; i< bitMatrix.getWidth(); i++){
            for (int j=0; j<bitMatrix.getHeight(); j++){
                image.setRGB(i, j, bitMatrix.get(i, j) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }
        if(imgPath == null || imgPath.equals("")){
            return image;
        }
        //插入logo图片
        QRcodeUtils.insertLogoImage(image, imgPath, needCompress);
        return image;
    }

    /****
     * 插入logo图片
     * @param bufferedImage :二维码图片
     * @param imageLogoPath :LOGO图片地址
     * @param needCompress  :是否压缩
     * @throws IOException
     */
    public static void insertLogoImage(BufferedImage bufferedImage, String imageLogoPath, boolean needCompress) throws IOException {
        //创建File对象
        File file = new File(imageLogoPath);
        if(!file.exists()){
            System.err.println(imageLogoPath+" 该图片不存在!");
            return;
        }
        Image imageLogo = ImageIO.read(file);
        int width = imageLogo.getWidth(null);
        int height = imageLogo.getHeight(null);
        //压缩Logo
        if(needCompress){
            if(width > WIDTH){
                width =WIDTH;
            }
            if (height > HEIGHT){
                height = HEIGHT;
            }
            //开始绘制logo图片
            Image image = imageLogo.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics graphics = bi.getGraphics();
            graphics.drawImage(image, 0, 0, null);
            graphics.dispose();
            imageLogo = image;
        }
        //插入logo
        Graphics2D graphics2D = bufferedImage.createGraphics();
        int x = (QRCODE_SIZE - width)/2;
        int y = (QRCODE_SIZE - height)/2;
        graphics2D.drawImage(imageLogo, x, y, width, height, null);
        Shape shape = new RoundRectangle2D.Float(x, y, width, height, 6, 6);
        graphics2D.setStroke(new BasicStroke(3f));
        graphics2D.draw(shape);
        graphics2D.dispose();

    }

}
